/******************************************************************************/
/*                                                                            */
/*  Copyright (c) 2009: ngi-central.org                                       */
/*  All rights reserved.                                                      */
/*                                                                            */
/******************************************************************************/


/// \file
/// This file implements a common base class for all geometric primitives.

#ifndef __sgl_geometric_primitive_h__
#define __sgl_geometric_primitive_h__

#include <sgl/global_settings.h>
#include <sgl/conditions.h>

namespace sgl {


/******************************************************************************/
/*                                                                            */
/* geometric_primitive                                                        */
/*                                                                            */
/******************************************************************************/

template <
	/// The dimensionality. 
	//!
	//! This defaults to two dimensions.
	size_t D=2,
	/// The element type. 
	//! 
	//! This type defaults to SGL_FPTYPE (which in turn defaults to double), but 
	//! any other numeric type is also suitable.
	typename T=SGL_FPTYPE>
/// A geometric primitive.
//!
//! This class serves as a base class of geometric primitives.
class geometric_primitive
{
public:
	/// The value type.
	typedef T value_type;

	/// The constant reference type.
	typedef T const & const_reference;

	/// The reference type.
	typedef T & reference;

	/// Find the dimensionality of the point.
	//!
	//! /return The dimensionality of the point.
	static size_t dimensions()
	{
		return D;
	}

	enum geometric_type
	{
		/// The vector type.
		//!
		//! A vector is composed of N components, where N equals the 
		//! dimensionality of the vector.
		vector,

		/// The direction type.
		//!
		//! A direction is composed of N-1 angles, where N equals the 
		//! dimensionality of the direction.
		direction,

		/// The point type.
		//!
		//! A point is composed of N components, where N equals the 
		//! dimensionality of the point.
		point,

		/// The ray type.
		//!
		//! A ray is composed of a point and a direction of the same 
		//! dimensionality. It starts at the point and extends along the 
		//!! direction to infinity.
		ray,

		/// The line type.
		//!
		//! A line is composed of a point and a direction of the same
		//! dimensionality. It starts at the point and extends both along the 
		//! direction as well as along the opposite direction to infinity.
		line,

		/// The line_segment type.
		//!
		//! A line_segment is composed of a point and a direction of the same 
		//! dimensionality. It starts at the point and extends along the 
		//!! direction given a certain extent.
		line_segment,

		/// The box type.
		//!
		//! A box represents an axis-parallel box. It is composed of a point and
		//! a vector.
		box,

		/// The circle type.
		//!
		//! A circle is composed of a center point and a scalar radius.
		hyper_sphere,

		/// The ellipse type.
		//!
		//! An ellipse is composed of a center point and a vectorial radius.
		hyper_ellipsoid,

		/// The polygon type.
		//!
		//! A polygon is a set of points connected with line segments.
		polygon,

		/// The triangle type.
		//!
		//! A triangle is a polygon with three vertices.
		triangle,

		/// The quadrilateral type.
		//!
		//! A quadrilateral is a polygon with four vertices.
		quadrilateral,
	};
};


} // namespace sgl

#endif // __sgl_geometric_primitive_h__
